package com.dis.user.aspect;

import com.dis.common.annotation.CheckPermission;
import com.dis.common.context.BaseContext;
import com.dis.common.exception.PermissionDeniedException;
import com.dis.user.mapper.PermissionMapper;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 权限检查切面
 */
@Aspect
@Component
@Slf4j
public class PermissionCheckAspect {

    @Autowired
    private PermissionMapper permissionMapper;

    /**
     * 定义切入点：所有使用CheckPermission注解的方法
     */
    @Pointcut("@annotation(com.dis.common.annotation.CheckPermission)")
    public void checkPermission() {
    }

    /**
     * 前置通知：在目标方法执行前进行权限检查
     */
    @Before("checkPermission()")
    public void before(JoinPoint joinPoint) {
        // 获取当前登录用户ID
        Long userId = BaseContext.getCurrentId();
        if (userId == null) {
            throw new PermissionDeniedException("用户未登录");
        }

        // 获取目标方法上的注解
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();                     // 获取方法签名
        Method method = signature.getMethod();                                                              // 获取方法
        CheckPermission annotation = method.getAnnotation(CheckPermission.class);                                   // 获取注解
        
        // 获取注解中的权限编码
        String permissionCode = annotation.value();
        
        // 查询用户是否拥有该权限
        List<String> permissions = permissionMapper.selectApisByUserId(userId)
                .stream()
                .map(p -> p.getPermissionCode())
                .collect(Collectors.toList());
        
        // 超级管理员拥有所有权限
        boolean isAdmin = permissionMapper.isUserAdmin(userId);
        
        if (!isAdmin && !permissions.contains(permissionCode)) {
            log.warn("用户{}没有{}权限", userId, permissionCode);
            throw new PermissionDeniedException("没有操作权限");
        }
    }
} 